﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace ChineseChess_Console
{
    class Board
    {
        private Piece[,] _piece;

        public Board()
        {
            _piece = new Piece[10, 9];
            int i;
            //int j;
            
            //Piece cua side 1
            _piece[0, 0] = new Piece(0, 0, 6, 1);
            _piece[0, 1] = new Piece(0, 1, 4, 1);
            _piece[0, 2] = new Piece(0, 2, 3, 1);
            _piece[0, 3] = new Piece(0, 3, 2, 1);
            _piece[0, 4] = new Piece(0, 4, 7, 1);
            _piece[0, 5] = new Piece(0, 5, 2, 1);
            _piece[0, 6] = new Piece(0, 6, 3, 1);
            _piece[0, 7] = new Piece(0, 7, 4, 1);
            _piece[0, 8] = new Piece(0, 8, 6, 1);

            _piece[2, 1] = new Piece(2, 1, 5, 1);
            _piece[2, 7] = new Piece(2, 7, 5, 1);

            i = 3;
            for (int j = 0; j < 9; j+= 2)
            {
                _piece[i, j] = new Piece(i, j, 1, 1);
            }

            //Piece cua side 2
            i = 6;
            for (int j = 0; j < 9; j += 2)
            {
                _piece[i, j] = new Piece(i, j, 1, 2);
            }

            _piece[7, 1] = new Piece(7, 1, 5, 2);
            _piece[7, 7] = new Piece(7, 7, 5, 2);

            _piece[9, 0] = new Piece(9, 0, 6, 2);
            _piece[9, 1] = new Piece(9, 1, 4, 2);
            _piece[9, 2] = new Piece(9, 2, 3, 2);
            _piece[9, 3] = new Piece(9, 3, 2, 2);
            _piece[9, 4] = new Piece(9, 4, 7, 2);
            _piece[9, 5] = new Piece(9, 5, 2, 2);
            _piece[9, 6] = new Piece(9, 6, 3, 2);
            _piece[9, 7] = new Piece(9, 7, 4, 2);
            _piece[9, 8] = new Piece(9, 8, 6, 2);

            //Cac o co trong
            for(i = 1; i < 9; ++i)
                for (int j = 0; j < 9; ++j)
                {
                    if(i == 2 || i == 7)
                        if (j == 0 || j == 2 || j == 3 || j == 4 || j == 5 || j == 6 || j == 8)
                        {
                            _piece[i, j] = new Piece(i, j, 0, 0);
                        }
                    if (i == 3 || i == 6)
                        if (j == 1 || j == 3 || j == 5 || j == 7)
                        {
                            _piece[i, j] = new Piece(i, j, 0, 0);
                        }
                    if (i == 1 || i == 4 || i == 5 || i == 8)
                        _piece[i, j] = new Piece(i, j, 0, 0);
                }
        }

        public void Print()
        {
            Console.WriteLine("\n===================******===================");
            for (int i = 0; i < 10; ++i)
            {
                for (int j = 0; j < 9; ++j)
                {
                    if (_piece[i, j].value != 0)
                    {
                        Console.Write("[");
                        switch (_piece[i, j].value)
                        {
                            case 1:
                                Console.Write("P");
                                break;
                            case 2:
                                Console.Write("G");
                                break;
                            case 3:
                                Console.Write("E");
                                break;
                            case 4:
                                Console.Write("H");
                                break;
                            case 5:
                                Console.Write("C");
                                break;
                            case 6:
                                Console.Write("R");
                                break;
                            case 7:
                                Console.Write("K");
                                break;
                        }
                        //Console.Write("_");
                        if (_piece[i, j].side == 1)
                            Console.Write("1]");
                        else
                            Console.Write("2]");
                    }
                    else
                        if(i == 3 || i == 6)
                            Console.Write("------");
                        else
                            Console.Write("-----");
                    if (j < 8 && (i == 0 || i == 9))
                        Console.Write("-");
                }
                if (i < 9)
                {
                    if(i != 4)
                        Console.Write("\n |    |    |    |    |    |    |    |    |\n");
                    else
                        Console.Write("\n |                                       |\n");
                }
            }
            Console.WriteLine("\n===================******===================");
        }

        public int Move(int side)
        {
            int currRow;
            int currCol;
            int newRow;
            int newCol;
            int winner = 0;
            // Mark piece
            do{
                Console.Write("\nChon quan co muon di chuyen:\n");
                Console.Write("row = ");
                currRow = int.Parse(Console.ReadLine());
                //Console.Write(currX.ToString());
                Console.Write("col = ");
                currCol = int.Parse(Console.ReadLine());
            }while((currRow < 0 || 9 < currRow) || (currCol < 0 || 8 < currCol)
                || (_piece[currRow, currCol].side != side) || (_piece[currRow, currCol].value == 0));
            Console.Write(_piece[currRow, currCol].value.ToString(), "\n");

            // Chon o co muon di chuyen quan co toi
            do{
                Console.Write("\nChon o co muon toi:\n");
                Console.Write("row = ");
                newRow = int.Parse(Console.ReadLine());
                Console.Write("col = ");
                newCol = int.Parse(Console.ReadLine());
            }while((newRow < 0 || 9 < newRow) || (newCol < 0 || 8 < newCol)
                || !Check(currRow, currCol, newRow, newCol) || (newRow == currRow && newCol == currCol));
            Console.Write(_piece[newRow, newCol].value.ToString(), "\n");

            if (_piece[newRow, newCol].value == 7)
                winner = _piece[currRow, currCol].side;
            _piece[newRow, newCol] = new Piece(newRow, newCol, _piece[currRow, currCol].value, side);
            _piece[currRow, currCol] = new Piece(currRow, currCol);

            return winner;
        }

        public bool Check(int currRow, int currCol, int newRow, int newCol)
        {
            if (_piece[newRow, newCol].side == _piece[currRow, currCol].side)
                return false;
            //Pawn
            if (_piece[currRow, currCol].value == 1)
            {
                //Side 1
                if(_piece[currRow, currCol].side == 1)
                {
                    if (currRow < 5)
                    {                    
                        if (newRow - currRow == 1 && newCol == currCol)
                            return true;
                    }
                    else
                        if ((newRow - currRow == 1 && newCol == currCol) || (newRow == currRow && Math.Abs(newCol - currCol) == 1))
                            return true;
                }

                // Side 2
                if (_piece[currRow, currCol].side == 2)
                {
                    if (currRow > 4)
                    {
                        if (newRow - currRow == -1 && newCol == currCol)
                            return true;
                    }
                    else
                        if ((newRow - currRow == -1 && newCol == currCol) || (newRow == currRow && Math.Abs(newCol - currCol) == 1))
                            return true;
                }
            }

            //Guard
            if (_piece[currRow, currCol].value == 2)
            {
                //Side 1
                if(_piece[currRow, currCol].side == 1)
                {
                    if (newRow < 2 && (2 < newCol && newCol < 6))
                        if (Math.Abs(newRow - currRow) == 1 && Math.Abs(newCol - currCol) == 1)
                            return true;
                }
                //Side 2
                if (_piece[currRow, currCol].side == 2)
                {
                    if (newRow > 6 && (2 < newCol && newCol < 6))
                        if (Math.Abs(newRow - currRow) == 1 && Math.Abs(newCol - currCol) == 1)
                            return true;
                }
            }
            
            //Elephant
            if(_piece[currRow, currCol].value == 3)
            {
                if (_piece[(newRow + currRow) / 2, (newCol + currCol) / 2].value != 0)
                    return false;
                // Side 1
                if(_piece[currRow, currCol].side == 1)
                {
                    if (newRow < 5)
                        if (Math.Abs(newRow - currRow) == 2 && Math.Abs(newCol - currCol) == 2)
                            return true;
                }
                //Side 2
                if (_piece[currRow, currCol].side == 2)
                {
                    if (newRow > 4)
                        if (Math.Abs(newRow - currRow) == 2 && Math.Abs(newCol - currCol) == 2)
                            return true;
                }
            }

            // Horse
            if(_piece[currRow, currCol].value == 4)
            {
                // Side 1 || Side 2
               
                    if (Math.Abs(newRow - currRow) == 1 && Math.Abs(newCol - currCol) == 2)
                    {
                        if(_piece[currRow, (newCol + currCol)/2].value != 0)
                            return false;
                        return true;
                    }
                    if (Math.Abs(newRow - currRow) == 2 && Math.Abs(newCol - currCol) == 1)
                    {
                        if(_piece[(newRow + currRow)/2, currCol].value != 0)
                            return false;
                        return true;
                    }
            }

            // Cannon
            if(_piece[currRow, currCol].value == 5)
            {
                //Side 1 , Side 2
                if (newRow == currRow)
                {
                    int t = -1;
                    int n = 0;
                    if (newCol < currCol)
                    {
                        t = newCol;
                        n = currCol;
                    }
                    else
                    {
                        t = currCol;
                        n = newCol;
                    }
                    for (int i = t + 1; i < n; ++i)
                        if (_piece[currRow, i].value != 0)
                        {
                            if(_piece[newRow, newCol].value == 0)
                                return false;
                            if (_piece[newRow, newCol].side != _piece[currRow, currCol].side)
                                return true;
                        }
                    if (_piece[newRow, newCol].value != 0)
                        return false;
                    else
                        return true;
                }

                if (newCol == currCol)
                {
                    int t = -1;
                    int n = 0;
                    if (newRow < currRow)
                    {
                        t = newRow;
                        n = currRow;
                    }
                    else
                    {
                        t = currRow;
                        n = newRow;
                    }
                    for (int i = t + 1; i < n; ++i)
                        if (_piece[i, currCol].value != 0)
                        {
                            if (_piece[newRow, newCol].value == 0)
                                return false;
                            if (_piece[newRow, newCol].side != _piece[currRow, currCol].side)
                                return true;
                        }
                    if (_piece[newRow, newCol].value != 0)
                        return false;
                }
            }

            // Rook
            if(_piece[currRow, currCol].value == 6)
            {
                int t = -1;
                int n = 0;
                if (newRow == currRow)
                {
                    if (currCol < newCol)
                    {
                        t = currCol;
                        n = newCol;
                    }
                    else
                    {
                        t = newCol;
                        n = currCol;
                    }
                    for (int i = t + 1; i < n; ++i)
                    {
                        if (_piece[currRow, i].value != 0)
                            return false;
                    }
                    return true;
                }
                if (newCol == currCol)
                {
                    if (currRow < newRow)
                    {
                        t = currRow;
                        n = newRow;
                    }
                    else
                    {
                        t = newRow;
                        n = currRow;
                    }
                    for (int i = t + 1; i < n; ++i)
                    {
                        if (_piece[i, currCol].value != 0)
                            return false;
                    }
                    return true;
                }
            }

            //King
            if(_piece[currRow, currCol].value == 7)
            {               
                //Side 1
                if (_piece[currRow, currCol].side == 1)
                {
                    if (newRow < 3 && (2 < newCol && newCol < 6))
                        if ((newRow == currRow && Math.Abs(newCol - currCol) == 1)
                            || (Math.Abs(newRow - currRow) == 1 && newCol == currCol))
                            return true;
                }
                //Side 2
                if (_piece[currRow, currCol].side == 2)
                {
                    if (newRow > 6 && (2 < newCol && newCol < 6))
                        if ((newRow == currRow && Math.Abs(newCol - currCol) == 1)
                            || (Math.Abs(newRow - currRow) == 1 && newCol == currCol))
                            return true;
                }
            }
            return false;
        }
    }
}
